package cn.yto.print.controller;

import cn.yto.print.AssistantApplication;
import cn.yto.print.config.CustomWindowEvent;
import cn.yto.print.config.i18n.LocaleLanguageSubject;
import cn.yto.print.enums.PluginRegistryEnum;
import cn.yto.print.system.SystemTrayManager;
import cn.yto.print.system.version.SystemUpdateChecker;
import cn.yto.print.utils.CommonUtil;
import cn.yto.print.utils.FxToastUtil;
import cn.yto.print.utils.PluginInstalledUtil;
import cn.yto.print.view.BluetoothView;
import cn.yto.print.view.HistoryView;
import cn.yto.print.view.IndexView;
import cn.yto.print.view.SerialPortView;
import de.felixroske.jfxsupport.FXMLController;
import de.felixroske.jfxsupport.GUIState;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.stage.Modality;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Locale;
import java.util.ResourceBundle;

@Slf4j
@FXMLController
public class MenuController extends BaseController implements Initializable {

    @FXML
    private Menu settingMenu;
    @FXML
    private MenuItem restartAppItem;
    @FXML
    private Menu openCatalogItem;
    @FXML
    private MenuItem assistMenuItem;
    @FXML
    private MenuItem caiNiaoMenuItem;
    @FXML
    private MenuItem tikTokMenuItem;
    @FXML
    private MenuItem wphMenuItem;
    @FXML
    private MenuItem pddMenuItem;
    @FXML
    private MenuItem deWuMenuItem;
    @FXML
    private MenuItem jdMenuItem;
    @FXML
    private MenuItem xhsnMenuItem;
    @FXML
    private MenuItem kuaiShouMenuItem;
    @FXML
    private MenuItem wxsphMenuItem;
    @FXML
    private MenuItem aiKuCunMenuItem;
    @FXML
    private Menu languageMenu;
    @FXML
    private MenuItem openDebugItem;
    @FXML
    private Menu printMenu;
    @FXML
    private MenuItem statusMonitorItem;
    @FXML
    private MenuItem printHistoryItem;
    @FXML
    private Menu weighMenu;
    @FXML
    private MenuItem serialMenuItem;
    @FXML
    private MenuItem bluetoothMenuItem;
    @FXML
    private Menu helpMenu;
    @FXML
    private MenuItem aboutMenuItem;
    @FXML
    private MenuItem clearMenuItem;
    @FXML
    private MenuItem updateMenuItem;

    @Autowired
    private LocaleLanguageSubject localePublisher;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        settingMenu.textProperty().bind(I18N.getStringBinding("menu.setting.show"));
        restartAppItem.textProperty().bind(I18N.getStringBinding("menu.setting.restart"));
        openCatalogItem.textProperty().bind(I18N.getStringBinding("menu.setting.catalog"));
        assistMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.assist"));
        caiNiaoMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.cainiao"));
        tikTokMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.tiktok"));
        wphMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.wph"));
        pddMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.pdd"));
        deWuMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.dewu"));
        jdMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.jd"));
        xhsnMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.xiaohongshux"));
        kuaiShouMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.kuaishou"));
        wxsphMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.wxsph"));
        aiKuCunMenuItem.textProperty().bind(I18N.getStringBinding("print.plugin.aikucun"));
        languageMenu.textProperty().bind(I18N.getStringBinding("menu.setting.switch"));
        openDebugItem.textProperty().bind(I18N.getStringBinding("menu.setting.debug"));
        printMenu.textProperty().bind(I18N.getStringBinding("menu.print.show"));
        statusMonitorItem.textProperty().bind(I18N.getStringBinding("menu.print.status"));
        printHistoryItem.textProperty().bind(I18N.getStringBinding("menu.print.histroy"));
        weighMenu.textProperty().bind(I18N.getStringBinding("menu.weigt.show"));
        bluetoothMenuItem.textProperty().bind(I18N.getStringBinding("menu.weigt.bluetooth"));
        serialMenuItem.textProperty().bind(I18N.getStringBinding("menu.weigt.serialPort"));
        helpMenu.textProperty().bind(I18N.getStringBinding("menu.help.show"));
        aboutMenuItem.textProperty().bind(I18N.getStringBinding("menu.help.about"));
        clearMenuItem.textProperty().bind(I18N.getStringBinding("menu.help.clear"));
        updateMenuItem.textProperty().bind(I18N.getStringBinding("menu.help.update"));
    }

    public void restartApp() {
        log.info("点击 [ 设置 - 重新启动 ] ");
        performAppRestart();
    }

    private void performAppRestart() {
        SystemTrayManager.restartApp();
    }

    public void showLog() {
        log.info("点击 [ 设置 - 打开调试 ] ");
        try {
            openLogWindow("/fxml/logger.fxml", "menu.catalog.title");
        } catch (Exception e) {
            log.error("打开调试日志异常", e);
        }
    }

    private void openLogWindow(String fxmlPath, String titleKey) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlPath));
        Parent root = loader.load();
        LoggerController controller = loader.getController();
        Scene scene = new Scene(root);
        Stage logStage = new Stage();
        logStage.getIcons().add(new Image("image/icon.png"));
        logStage.setScene(scene);
        logStage.setTitle(I18N.get(titleKey));
        controller.initializeStage(logStage);
        logStage.initModality(Modality.APPLICATION_MODAL);
        logStage.show();
    }

    public void openLogDir(ActionEvent event) {
        String logDir = resolveLogDirectory((MenuItem) event.getSource());
        if (logDir == null) {
            return;
        }
        openFolder(new File(logDir));
    }

    private String resolveLogDirectory(MenuItem selectedItem) {
        PluginRegistryEnum pluginType = PluginRegistryEnum.getPluginByCode((String) selectedItem.getUserData());
        if (pluginType == null) {
            return CommonUtil.getCurrentDir("logs");
        } else {
            String path = PluginInstalledUtil.getPluginInstallPath(pluginType);
            if (StringUtils.isBlank(path)) {
                Platform.runLater(() -> super.showAlert(I18N.get("menu.catalog.alert")));
                return null;
            }
            return CommonUtil.getParentPath(path);
        }
    }

    private void openFolder(File folder) {
        if (!folder.exists()) {
            super.showAlert(I18N.get("menu.catalog.alert"));
            return;
        }
        try {
            Desktop.getDesktop().open(folder);
            log.info("点击 [ 设置 - 日志目录]：{}", folder.getAbsolutePath());
        } catch (Exception e) {
            log.error("打开日志目录异常", e);
        }
    }

    public void switchLanguage(ActionEvent event) {
        String localeCode = (String) ((MenuItem) event.getSource()).getUserData();
        setLocaleByCode(localeCode);
        localePublisher.publishChangeEvent();
        log.info("点击 [ 设置 - 语言切换 ]：{}", localeCode);
    }

    private void setLocaleByCode(String localeCode) {
        if ("zh_CN".equals(localeCode)) {
            I18N.setLocale(Locale.CHINESE);
        } else if ("en_US".equals(localeCode)) {
            I18N.setLocale(Locale.ENGLISH);
        } else {
            I18N.setLocale(Locale.CHINESE);
        }
    }

    public void selectMode(Event event) {
        Platform.runLater(() -> GUIState.getStage().fireEvent(new CustomWindowEvent(CustomWindowEvent.CLOSE_SHOW)));
        processMode(((MenuItem) event.getSource()).getUserData().toString());
    }

    private void processMode(String mode) {
        switch (mode) {
            case "serialPort":
                log.info("点击 [ 称重 - 串口模式 ] ");
                AssistantApplication.showView(SerialPortView.class);
                Platform.runLater(() -> GUIState.getStage().fireEvent(new CustomWindowEvent(CustomWindowEvent.SERIALPORT_SHOW)));
                break;
            case "bluetooth":
                log.info("点击 [ 称重 - 蓝牙模式 ] ");
                AssistantApplication.showView(BluetoothView.class);
                Platform.runLater(() -> GUIState.getStage().fireEvent(new CustomWindowEvent(CustomWindowEvent.BLUETOOTH_SHOW)));
                break;
            default:
                break;
        }
    }

    public void printHelper(Event event) {
        log.info("点击 [ 打印 - 状态监控 ] ");
        AssistantApplication.showView(IndexView.class);
        Platform.runLater(() -> GUIState.getStage().fireEvent(new CustomWindowEvent(CustomWindowEvent.CLOSE_SHOW)));
    }

    public void printHistory(Event event) {
        log.info("点击 [ 打印 - 打印记录 ] ");
        AssistantApplication.showView(HistoryView.class);
        Platform.runLater(() -> GUIState.getStage().fireEvent(new CustomWindowEvent(CustomWindowEvent.CLOSE_SHOW)));
    }

    public void showAbout() {
        log.info("点击 [ 帮助 - 关于我们 ] ");
        try {
            openAboutDialog("/fxml/About.fxml", "menu.help.about", "css/about.css");
        } catch (Exception e) {
            log.error("关于我们异常", e);
        }
    }

    private void openAboutDialog(String fxmlPath, String titleKey, String cssPath) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlPath), I18N.getResourceBundle());
        Parent root = loader.load();
        Scene scene = new Scene(root);
        scene.getStylesheets().add(cssPath);
        Stage dialogStage = new Stage();
        dialogStage.setTitle(I18N.get(titleKey));
        dialogStage.setScene(scene);
        dialogStage.getIcons().add(new Image("image/icon.png"));
        dialogStage.setResizable(false);
        dialogStage.initModality(Modality.APPLICATION_MODAL);
        dialogStage.show();
    }

    public void openUrl() {
        log.info("点击 [ 帮助 - 访问官网 ] ");
        try {
            Desktop.getDesktop().browse(new URI("https://ywmsw.yto.net.cn/"));
        } catch (Exception e) {
            log.error("访问官网异常", e);
        }
    }

    public void clearCache() {
        log.info("点击 [ 帮助 - 清理缓存 ] ");
        Platform.runLater(() -> {
            GUIState.getStage().fireEvent(new CustomWindowEvent(CustomWindowEvent.CLEAR_CACHE));
            FxToastUtil.showToast(I18N.get("menu.help.toast"));
        });
    }

    public void checkUpdate() {
        log.info("点击 [ 帮助 - 检查更新 ] ");
        SystemUpdateChecker.checkForUpdate(true);
    }

}

